﻿// ***********************************************************************
// Assembly         : OSS.Earth
// Author           : tian_
// Created          : 08-15-2019
//
// Last Modified By : tian_
// Last Modified On : 10-30-2019
// ***********************************************************************
// <copyright file="VideoTestCmd.cs" company="">
//     Copyright ©  2017
// </copyright>
// <summary></summary>
// ***********************************************************************
using System.IO;
using OsgEarth;
using Osg;
using ZFGK.Addins;
using ZFGK.OSG.UI;
using ZFGK.OSG.Utility;
using ZFGK.osgEarth.UI;
using ZFGK.WinForms.Utility;

namespace OSS.Earth.Commands.UserTestCmds
{
    /// <summary>
    /// Class VideoTestCmd.
    /// </summary>
    /// <seealso cref="ZFGK.Addins.IExtendCommand" />
    public class VideoTestCmd : IExtendCommand
    {
        /// <summary>
        /// Executes the specified command data.
        /// </summary>
        /// <param name="cmdData">The command data.</param>
        /// <param name="message">The message.</param>
        /// <returns>CmdResult.</returns>
        public CmdResult Execute(ExtendCmdData cmdData, ref string message)
        {
            var form = cmdData.ViewForm as OsgEarthViewForm;
            var osgEarthViewCtrl = form.OsgEarthViewCtrl;
            var actionUtility = osgEarthViewCtrl.ActionUtility;

            string filePath = null;
            if (!DialogUtil.OpenText(out filePath))
            {
                return CmdResult.Cancel;
            }

            Vec3d mapPt = null;
            // 选择插入点
            if (!actionUtility.PickEarthPoint("选择插入点", out mapPt))
                return CmdResult.Cancel;

            float length = 160.0f, width = length * 0.75f;

            var list = File.ReadAllLines(filePath);
//             var list = new[]
//             {
//                 "rtsp://user:zfgk1234@192.168.1.64:554/h264/ch1/main/av_stream",
//                 "rtsp://user:zfgk1234@192.168.1.64:554/h264/ch1/main/av_stream",
//                 "rtsp://user:zfgk1234@192.168.1.64:554/h264/ch1/main/av_stream",
//                 "rtsp://user:zfgk1234@192.168.1.64:554/h264/ch1/main/av_stream",
//                 "rtsp://user:zfgk1234@192.168.1.64:554/h264/ch1/main/av_stream"
//             };

            var readerWriter = OsgDB.Registry.instance().getReaderWriterForExtension("ffmpeg");

            var group = new Group();

            int index = 0;
            foreach (var s in list)
            {
                var readResult = readerWriter.readImage(s);
                var image = readResult.getImage();
                if (!image.IsValid || !image.valid())
                {
                    //ZfMessageUtil.("打开图像文件失败！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    continue;
                }
                var imageStream = new ImageStream(image);
                if (imageStream.IsValid && imageStream.valid())
                {
                    imageStream.play();
                }
                var geode = VideoNode(length, width, image);

                var trf = new MatrixTransform(Matrixd.translate(0, index++ * width, 0));
                trf.addChild(geode);
                group.addChild(trf);
            }
            //OsgEarth.Annotation.ImageOverlay()
            mapPt.z = 0;
            var geoPoint = new GeoPoint(osgEarthViewCtrl.OsgEarthObj.MapNode.getMapSRS(), mapPt, AltitudeMode.ALTMODE_RELATIVE);
            var geoTransform = new GeoTransform();
            geoTransform.setPosition(geoPoint);
            geoTransform.addChild(OsgAutoTransformUtil.CreateInfoNode(new Vec3d(), 30, group));

            //var osgNode = new OsgNode("annotation", new NodeData("1", geoTransform));
            osgEarthViewCtrl.OsgEarthObj.AddOrReplaceModel("annotation", geoTransform, "1");

            return CmdResult.Succeed;
        }

        /// <summary>
        /// Videoes the node.
        /// </summary>
        /// <param name="length">The length.</param>
        /// <param name="width">The width.</param>
        /// <param name="image">The image.</param>
        /// <returns>Geode.</returns>
        private static Geode VideoNode(float length, float width, Image image)
        {
            var geometryBuilder = new OsgGeometryBuilder();
            geometryBuilder.AddVert(new Vec3f(-length * 0.5f, 0, 0));
            geometryBuilder.AddVert(new Vec3f(length * 0.5f, 0, 0));
            geometryBuilder.AddVert(new Vec3f(length * 0.5f, width, 0));
            geometryBuilder.AddVert(new Vec3f(-length * 0.5f, width, 0));
            geometryBuilder.AddPrimitiveSet(0u, 1, 2, 3);

            var geom = geometryBuilder.ToGeometry(new ElementBufferObject());
            //为纹理创建数组
            var texCoordArray = new Vec2Array(); //创建一个 Vec2Array对象以保存纹理单元 0 的纹理坐标

            texCoordArray.push_back(new Vec2f(0, 1));
            texCoordArray.push_back(new Vec2f(1, 1));
            texCoordArray.push_back(new Vec2f(1, 0));
            texCoordArray.push_back(new Vec2f(0, 0));
            geom.setTexCoordArray(0, texCoordArray);

            //向Geode类添加几何体（Drawable）
            var geode = new Geode();
            geode.addDrawable(geom);

            var stateSet = geode.getOrCreateStateSet();
            stateSet.setMode(GL.GL_LIGHTING, (uint)StateAttribute.Values.OFF);
            //将图像关联到Texture 2D对象
            var texture2D = new Texture2D();
            texture2D.setImage(image);
            // 创建纹理对象后,释放内部的ref_ptr<Image>,删除Image图像。
            texture2D.setUnRefImageDataAfterApply(true);

            texture2D.setResizeNonPowerOfTwoHint(false);
            texture2D.setFilter(Osg.Texture.FilterParameter.MIN_FILTER, Osg.Texture.FilterMode.LINEAR);
            texture2D.setFilter(Osg.Texture.FilterParameter.MAG_FILTER, Osg.Texture.FilterMode.LINEAR);
            texture2D.setWrap(Osg.Texture.WrapParameter.WRAP_S, Osg.Texture.WrapMode.CLAMP_TO_EDGE);
            texture2D.setWrap(Osg.Texture.WrapParameter.WRAP_T, Osg.Texture.WrapMode.CLAMP_TO_EDGE);

            stateSet.setTextureAttributeAndModes(0, texture2D); //关联材质属性与模式到材质单元0
            return geode;
        }
    }
}
